package uk.co.q3c.deplan.server.util.validation.rules;

import java.io.Serializable;

import javax.persistence.Id;

import uk.co.q3c.deplan.client.domain.AbstractDomainObject;
import uk.co.q3c.deplan.client.domain.DomainKind;
import uk.co.q3c.deplan.client.domain.DomainObject;
import uk.co.q3c.deplan.client.domain.resource.PersistenceReferenceException;
import uk.co.q3c.deplan.server.util.validation.ValidationResult;

import com.googlecode.objectify.Key;

public class IntegerCompare extends AbstractDomainObject implements ValidationObjectRule, Serializable {

	private static final long serialVersionUID = 2138001310911614201L;
	@Id
	private Long keyId;

	public enum Result {
		A_IS_LESS,
		EQUAL,
		B_IS_LESS
	};

	private String propertyNameA;
	private String propertyNameB;

	private final Result requiredResult;

	public IntegerCompare(String propertyNameA, String propertyNameB, Result requiredResult) {
		super();
		this.propertyNameA = propertyNameA;
		this.propertyNameB = propertyNameB;
		this.requiredResult = requiredResult;
	}

	/**
	 * 
	 * @see uk.co.q3c.deplan.util.validation.rules.ValidationObjectRule#validate
	 */
	@Override
	public ValidationResult validate(PropertyValuer valuer, ValidationResult vr) {
		int propertyA = (Integer) valuer.propertyValue(propertyNameA);
		int propertyB = (Integer) valuer.propertyValue(propertyNameB);
		if (propertyA < propertyB && requiredResult == Result.A_IS_LESS) {
			vr.setValid(true);
			return vr;
		}
		if (propertyA > propertyB && requiredResult == Result.B_IS_LESS) {
			vr.setValid(true);
			return vr;
		}

		if (propertyA == propertyB && requiredResult == Result.EQUAL) {
			vr.setValid(true);
			return vr;
		}
		String msg = "";
		switch (requiredResult) {
		case A_IS_LESS:
			msg = " less than ";
			break;
		case B_IS_LESS:
			msg = "more than ";
			break;

		case EQUAL:
			msg = " equals to ";
			break;
		}

		vr.addValidationMessage(propertyNameA + msg + propertyNameB);
		vr.setValid(false);
		return vr;
	}

	public String getPropertyNameA() {
		return propertyNameA;
	}

	public void setPropertyNameA(String propertyNameA) {
		this.propertyNameA = propertyNameA;
	}

	public String getPropertyNameB() {
		return propertyNameB;
	}

	public void setPropertyNameB(String propertyNameB) {
		this.propertyNameB = propertyNameB;
	}

	public Result getRequiredResult() {
		return requiredResult;
	}

	@Override
	public DomainKind getKind() {
		return DomainKind.Validation;
	}

	public Long getKeyId() {
		return keyId;
	}

	public void setKeyId(Long keyId) {
		this.keyId = keyId;
	}

	@Override
	public Key<? extends DomainObject> getKey() throws PersistenceReferenceException {
		throw new RuntimeException("Not yet implemented");
	}
}
